/**
 *
 *
 * API:
 * ------------------------
 *
 * query(selector, queryAll, parent) 获取元素
 * newLogger(name) 获取日志
 * merge(dest, src) 将src的内容合并到dest里面
 * i18n(key) 获取国际化信息
 * getXMLDoc(xml) 解析xml成XML对象
 *
 */
const WorkflowUtil = {};


/**
 * 是否是调试模式
 */
WorkflowUtil.isDebug = function(){
    return true;
};

/**
 * 选择器
 */
WorkflowUtil.query = function(selector, queryAll, parent) {

    const p = parent ? parent : document;
    if (queryAll) {
        return p.querySelectorAll(selector);
    } else {
        return p.querySelector(selector);
    }
};


/**
 * 日志对象
 */
const WorkflowLogger = (function(){


    const levels = {
        ERROR: 3,
        WARN: 4,
        INFO: 6,
        DEBUG: 7
    };
    const currrentLevel = "INFO";


    const Logger = function (name) {
        this.name = name;
    };

    Logger.prototype.debug = function(message, ignoreLevel){

        this._doLog(message, "DEBUG", ignoreLevel, "log");
    };

    Logger.prototype.info = function(message, ignoreLevel){

        this._doLog(message, "INFO", ignoreLevel, "info");
    };

    Logger.prototype.warn = function(message, ignoreLevel){

        this._doLog(message, "WARN", ignoreLevel, "warn");
    };

    Logger.prototype.error = function(message, e, ignoreLevel){

        this._doLog(message, "ERROR", ignoreLevel, "error", e);
    };

    /**
     * 日志输出
     */
    Logger.prototype._doLog = function(message, level, ignoreLevel, method, extObject){

        const thisLevel = level;
        if(WorkflowUtil.isDebug() || ignoreLevel || this._canLog(thisLevel)){

            const newMessage = this._preDealMsg(message, thisLevel);

            const logInfos = [];
            logInfos.push(newMessage);
            if(typeof message === 'object'){
                logInfos.push(message);
            }
            if(extObject){
                logInfos.push("\r\n");
                logInfos.push(extObject);
            }

            //console[method].apply(window, logInfos);
            //console[method](logInfos);
            switch (logInfos.length) {
              case 1:
              console[method](logInfos[0]);
                break;
              case 2:
              console[method](logInfos[0], logInfos[1]);
                break;
              case 3:
              console[method](logInfos[0], logInfos[1], logInfos[2]);
                break;
              case 4:
              console[method](logInfos[0], logInfos[1], logInfos[2], logInfos[3]);
                break;
              default:

            }
        }
    };

    Logger.prototype._preDealMsg = function(msg, level){

        let _blanks = "";
        if(level.length < 5){
            _blanks = " ";
        }

        let _ret = this.name + " : " + _blanks + level + " - ";

        if(typeof msg !== "object"){
            _ret += msg;
        }

        return _ret;
    };


    /**
     *
     * 校验日志级别
     *
     */
    Logger.prototype._canLog = function(level){

        let thisLevel, currentLevel;

        thisLevel = levels[level];
        currentLevel = levels[currrentLevel];

        return currentLevel >= thisLevel;
    };

    return Logger;
})();
/**
 * 日志
 *
 */
WorkflowUtil.newLogger = function(name){

    return new WorkflowLogger(name);
};

/**
 * 判断是否有属性
 */
WorkflowUtil.hasProp = {}.hasOwnProperty;

/**
 * 继承
 */
WorkflowUtil.extend = function(child, parent) {
    for (let key in parent) {
        if (parent.hasOwnProperty(key)){
            child[key] = parent[key];
        }
    }
    function Ator() {
        this.constructor = child;
    }
    Ator.prototype = parent.prototype;
    child.prototype = new Ator();
    child.__super__ = parent.prototype;
    return child;
};


/**
 * 合并json对象
 */
WorkflowUtil.merge = function(dest, src){

    for(let key in src){
        if(src.hasOwnProperty(key) && !dest[key]){
            dest[key] = src[key];
        }
    }
    return dest;
};

/**
 * 国际化配置
 */
WorkflowUtil.i18n = function(key){

    const args = arguments, I18nResource = window.I18nResource;

    let value = I18nResource[key];
    if(!value){
        return key;
    }

    if(args.length > 1){
        const params = Array.prototype.slice.call(args, 1);
        let i = 0, paramsLength = params.length;
        for(; i < paramsLength; i++){
            value = value.replace(new RegExp("\\{" + i + "\\}", "g"), params[i]);
        }
    }

    return value;
};

/**
 * 将XML解析成XML对象
 */
WorkflowUtil.getXMLDoc = function(xml){
    let xmlDoc = null;
    const ua = navigator.userAgent;
    const isMSIE = (navigator.appName === "Microsoft Internet Explorer") || ua.indexOf('Trident') !== -1;
    if(isMSIE){
        xmlDoc = new ActiveXObject("MSXML2.DOMDocument");
        xmlDoc.async=false;
        if(xml != null){
            xmlDoc.loadXML(xml);
        }
    }else{
        if(document.implementation && document.implementation.createDocument){
            xmlDoc = document.implementation.createDocument("","",null);
            const oParser = new DOMParser();
            xmlDoc.async = false;
            if(xml != null){
                xmlDoc = oParser.parseFromString(xml, "text/xml");
            }
        }
    }
    return xmlDoc;
};


/**
 * xml 对象转换成 字符串
 * @param xmlDoc
 * @returns {string}
 */
WorkflowUtil.xml2String = function (xmlDoc) {

    if (xmlDoc) {
        if (window.ActiveXObject) {
            return xmlDoc.xml;
        } else {
            return (new XMLSerializer()).serializeToString(xmlDoc);
        }
    }

    return "";
};

/**
 * 获取一个空的 XML 对象
 */
WorkflowUtil.getEmptyXMLDoc = function () {

    let xmlDoc;
    if (window.ActiveXObject) {
        xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    } else if (document.implementation
        && document.implementation.createDocument) {
        xmlDoc = document.implementation.createDocument('', '', null);
    } else {
        alert("your browser do not suport XML.");
        return;
    }
    return xmlDoc;
};




